; DESCRIPTION:
; Vertex shader used to render A3DMorphRigidMesh. this shader does below works:
; # vertex blending (4 morph channels) and transform
; # compute light = env_ambient + dir_light(ambient & diffuse & specular) + point_light(ambient & diffuse)
; # output texture coordinates

; CREATED BY: duyuxin, 2004/1/5
; Copyright (c) 2003 Archosaur Studio, All Rights Reserved.

vs.1.1

;------------------------------------------------------------------------------
; v0 	  = position
; v1 	  = normal
; v2 	  = texture coordinates
; v3-v4   = morph channel 0 position delta and normal delta
; v5-v6   = morph channel 1 position delta and normal delta
; v7-v8   = morph channel 2 position delta and normal delta
; v9-v10  = morph channel 3 position delta and normal delta
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Constants specified by the app;
;
; c15     = palette of world matrices (from model space to world space)
; c14     = palette of morph channel weight (4 weights)
; c13	  = point_light's attenuation
; c12	  = material ambient * point_light.ambient
; c11	  = material.diffuse * point_light.diffuse
; c10	  = point_light's position in world space
; c9	  = material.specular * dir_light.specular
; c8	  = material.diffuse * dir_light.diffuse
; c7	  = ambient color + emmisive color
; c6	  = eye's direction in world space
; c2-c5   = view matrix * projection matrix (from world space to cuboid space)
; c1	  = dir_light's direction in world space
; c0	  = {1, power, 0, 765.01};
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; oPos	  = Output position
; oD0	  = Diffuse
; oD1	  = Specular
; oT0	  = texture coordinates
;------------------------------------------------------------------------------

; ============ Morph vertex ================

; Calculate morph position and normal

mov r7, v0	; position in r7
mov r8, v1	; normal in r8

mad r7, c14.xxxx, v3, r7
mad r8, c14.xxxx, v4, r8

mad r7, c14.yyyy, v5, r7
mad r8, c14.yyyy, v6, r8

mad r7, c14.zzzz, v7, r7
mad r8, c14.zzzz, v8, r8

mad r7, c14.wwww, v9, r7
mad r8, c14.wwww, v10, r8

mov r7.w, c0.x	; set w to 1

; normalize normal
dp3 r8.w, r8, r8
rsq r8.w, r8.w
mul r8, r8, r8.w

; ============ Transform position and normal from model space to world space ==========

m4x3 r4, r7, c15
m3x3 r5, r8, c15 

; Transfrom position from world space to cuboid space and output it
mov r4.w, c0.x
m4x4 oPos, r4, c2

; Do we need to re-normalize normal ? We just did a rotation, so...
; dp3 r5.w, r5, r5
; rsq r5.w, r5.w
; mul r5, r5, r5.w

; ============ Calculate dynamic point light's diffuse ============

; point light pos - vertex position in world space
add r10.xyz, c10, -r4.xyz

; Normalize vector VERTEX_TO_LIGHT and calculate distance
; d = distance
dp3 r10.w, r10, r10  	; r10.w = d * d = (x*x) + (y*y) + (z*z)
rsq r11.w, r10.w     	; r11.w = 1 / d = 1 / ||V|| = 1 / sqrt(r10.w)
mul r11, r10, r11.w	; r11 = Normalized vector

mov r8, c0.zzzz		; clear r8
dp3 r8.x, r5, r11 	; N dot L
lit r8, r8		; compute light

; Calculate the attenuation
; r10.w = d * d
; r11.w = 1 / d
; r9 = (1, d*d*1/d, d*d, 1/d)
dst r9, r10.w, r11.w

dp3 r9.x, r9, c13	; (a0 + a1*d + a2*d*d)
rcp r9.x, r9.x

mul r1, r8, r9.xxxx	; Scale with the attenuation
mul r8, r1.y, c11	; Multiply with point_light's diffuse

; ============ Calculate directional light's diffuse and specular ============

mov r4, -c1
dp3 r1.x, r5, r4     	; normal dot light (N * L)
add r2, -c6, r4		; normalized half vector H = L + V

; renormalize H
dp3 r2.w, r2, r2
rsq r2.w, r2.w
mul r2, r2, r2.w

dp3 r1.y, r5, r2	; N dot H

; compute specular and clamp values (lit)
; r1.x - N dot L
; r1.y - N dot H
; r1.w - specular power n
mov r1.w, c0.y
lit r1, r1

mad r0, r1.y, c8, r8   	; Multiply with dir_light's diffuse then add point_light's diffuse
mad r0, r9.x, c12, r0  	; Add point_light's ambient * attenuation
add r0, r0, c7		; Add other ambient
min oD0, r0, c0.x     	; output diffuse, clamp if > 1

mul r4, r1.z, c9    	; Multiply with specular
mov r4.w, c0.x			; Set fog factor to 1
min oD1, r4, c0.x     	; output specular, clamp if > 1

; Copy texture coordinate
mov oT0, v2

